import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
var _excluded = ["children"];

/**
 * withProps 高阶组件 注入 props
 * @date 2019/09/01

 */
import React from 'react';
/**
 * 默认清除时间
 */

var CLEAN_CACHE_TIMEOUT = 10 * 1000 * 60;

/**
 * 缓存方法的返回值, 有点类似于单例模式，区别在于，调用 startTimeoutClean 之后会在指定时间内清除缓存，
 * 每次调用该方法是缓存时间重置。
 * @param {*} func 缓存的方法
 * @returns {Function} throttleTimeSingleFun 返回的包装后端方法
 * @returns {Function} throttleTimeSingleFun.startTimeoutClean 开始计时，当到达指定时候后清除缓存数据
 */
export function throttleTimeSingle(func) {
  if (typeof func !== 'function') {
    throw new TypeError('FUNC_ERROR_TEXT');
  }

  var result;
  var lastArgs;
  var lastThis;
  var timerId;

  function invokeFunc() {
    var args = lastArgs;
    var thisArg = lastThis;
    lastArgs = undefined;
    lastThis = undefined;
    result = func.apply(thisArg, args);
    return result;
  }

  var clean = function clean() {
    if (timerId !== undefined) {
      clearTimeout(timerId);
      timerId = undefined;
    }

    lastArgs = undefined;
    lastThis = undefined;
    timerId = undefined;
    result = undefined;
  };

  var startTimeoutClean = function startTimeoutClean() {
    var wait = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : CLEAN_CACHE_TIMEOUT;

    if (wait === 0) {
      clean();
      return;
    }

    if (timerId !== undefined) {
      clearTimeout(timerId);
    }

    timerId = setTimeout(clean, wait);
  };

  function throttleTimeSingled(that) {
    for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
      rest[_key - 1] = arguments[_key];
    }

    lastArgs = rest;
    lastThis = that;

    if (timerId === undefined) {
      return invokeFunc();
    }

    clearTimeout(timerId);
    return result;
  }

  throttleTimeSingled.startTimeoutClean = startTimeoutClean;
  throttleTimeSingled.clean = clean;
  return throttleTimeSingled;
}
/**
 * 高级组件 单例模式缓存props,并且在组件生命周期之后的指定时间后清除缓存
 * @param initPropsFun {()=>({ [key: string]: DataSet })} initPropsFun 返回一个 dataset map 的方法
 * @param options.cacheState {boolean} 是否缓存数据状态
 *
 * @example
 *  // initProps 是延迟运行的，initProps 返回的数据可以注入到组件的 props 里面
 *  const initProps = () => {
 *    const tableDS = new DataSet({
 *      ...dataSetProps(),
 *        autoQuery: true,
 *        exportUrl: '...',
 *    });
 *    return {
 *      tableDS,
 *    };
 *  };
 *  @withProps(initProps, { cacheState: true })
 *  export default class ListPage extends PureComponent {
 *    initWithProps() {
 *       // 这里可以完成 ds 的事件绑定, 或者对 initProps 返回的 Props 做一些持久化的修改
 *       this.props.tableDS.addEventListener('query', this.handleQueryEvent);
 *    }
 *    componentDidMount() {
 *      // 这里可以拿到通过时间缓存控制过的 initProps 的返回值
 *      console.log(this.props.tableDS);
 *   }
 * }
 */

export default function withProps(initPropsFun) {
  var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
      _ref$wait = _ref.wait,
      wait = _ref$wait === void 0 ? CLEAN_CACHE_TIMEOUT : _ref$wait,
      _ref$cacheState = _ref.cacheState,
      cacheState = _ref$cacheState === void 0 ? false : _ref$cacheState;

  var throttleTimeSingleFun = throttleTimeSingle(initPropsFun);
  return function (Components) {
    var WithPropsComponent = /*#__PURE__*/function (_React$Component) {
      _inherits(WithPropsComponent, _React$Component);

      var _super = _createSuper(WithPropsComponent);

      function WithPropsComponent(props) {
        var _this;

        _classCallCheck(this, WithPropsComponent);

        _this = _super.call(this, props);
        _this.state = throttleTimeSingleFun();
        return _this;
      }
      /**
       * FIXME: @WYQ
       * @param nextProps
       * @constructor
       */
      // eslint-disable-next-line camelcase


      _createClass(WithPropsComponent, [{
        key: "UNSAFE_componentWillReceiveProps",
        value: function UNSAFE_componentWillReceiveProps(nextProps) {
          var _this2 = this;

          var language = this.props.language;
          var nextLanguage = nextProps.language;

          if (language !== nextLanguage) {
            throttleTimeSingleFun.clean();
            setTimeout(function () {
              _this2.setState(throttleTimeSingleFun());
            }, 400);
          }
        }
      }, {
        key: "componentWillUnmount",
        value: function componentWillUnmount() {
          if (cacheState) {
            throttleTimeSingleFun.startTimeoutClean(wait);
          } else {
            throttleTimeSingleFun.clean();
          }
        }
      }, {
        key: "render",
        value: function render() {
          var _this$props = this.props,
              children = _this$props.children,
              otherProps = _objectWithoutProperties(_this$props, _excluded);

          return React.createElement(Components, _objectSpread(_objectSpread({}, this.state), otherProps), children);
        }
      }]);

      return WithPropsComponent;
    }(React.Component);

    return WithPropsComponent;
  };
}